package com.fingard.dsp.bank.directbank.fubon01;


import java.io.UnsupportedEncodingException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.codec.binary.Hex;



/**
 * 恒生核心系统MAC算法移植。他们将整个报文使用默认的12345678为密钥进行加密，算法是DES-ECB， 64位块长算法，自定义的填充方法(最少填一个块，填0x80打头的全0)
 * 这里假定运行环境JDK肯定支持DES/ECB/NoPadding加密，所以将所有的checked exception转化为runtime exception了
 * @author binarier
 *
 */
public class HSDES {

    /**
     * 使用"12345678"为密钥生成4字节的MAC，ASCII字符
     * @param datain 整个报文
     * @return 4字节的MAC，ASCII字符
     * @throws UnsupportedEncodingException
     */
    public static byte[] genMAC(byte datain[]) throws UnsupportedEncodingException
    {
        return genMAC(datain, "20301000".getBytes());
    }

    /**
     * 生成4字节的MAC，ASCII字符
     * @param datain 整个报文
     * @param key DES加密密钥
     * @return 4字节的MAC，ASCII字符
     */
    public static byte[] genMAC(byte datain[], byte key[])
    {
        try
        {
            //初始化密钥基础设施
            SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec(key));
            Cipher c = Cipher.getInstance("DES/ECB/NoPadding");
            c.init(Cipher.ENCRYPT_MODE, desKey);

            //至少补一个8字节块
            int len = (datain.length / 8 + 1) * 8;

            byte data[] = new byte[len];
            System.arraycopy(datain, 0, data, 0, datain.length);
            //补的数据以0x80打头，后面是0;
            data[datain.length] = (byte)0x80;

            //加密缓冲区
            byte buff[] = new byte[8];
            for (int j=0;j<len;j+=8)
            {
                //以8字节为一块循环
                for (int i=0;i<8;i++)
                {
                    if (j == 0)
                        buff[i] = data[i];
                    else
                        buff[i] ^= data[j + i];
                }
                buff = c.doFinal(buff);

                //使用加密后值的前四字节的大写HEX码作为下一次运算的值 —— 略奇葩
                char hex[] = Hex.encodeHex(buff, false);
                for (int i=0;i<8;i++)
                    buff[i] = (byte)hex[i];
            }

            //取最后值的前四字节为MAC值
            return buff;
        }
        catch (Exception e)
        {
            //所有异常都当运行时抛出
            throw new IllegalArgumentException(e);
        }
    }

    public static String toHexString(byte b[]) {
        StringBuffer hexString = new StringBuffer();
        for (int i = 0; i < b.length; i++) {
            String plainText = Integer.toHexString(0xff & b[i]);
            if (plainText.length() < 2)
                plainText = "0" + plainText;
            hexString.append(plainText);
        }
        return hexString.toString();
    }

    public static void main(String[] args) throws UnsupportedEncodingException{
//    	ResourceBundle resource = ConfigManager.getResourcePro();
//    	String aa = resource.getString("PAYHostName");
//        String str = "0162FOAFB0110000001                               IDDL120008575           张进益2                                          zhangjinyi                         TWNH";
        String str="0395EAIRT0112018005                                           0502          CA50200002100004419                                       RMB00000000040000+    5168888   N                           00000000000000+                           00000000000000+strinG 成                                                                                             2019010580010000020020190510                ";
        byte[] b = str.getBytes("GBK");
        /*StringBuilder stringBuilder = new StringBuilder("");    

        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        System.out.println(stringBuilder.toString());*/
        byte[] bb = genMAC(b);
        System.out.println(new String(bb));
        byte[] packet = new byte[b.length+4];
        System.arraycopy(b, 0, packet, 0, b.length);
        System.arraycopy(HSDES.genMAC(b),0,packet,b.length,4);
        System.out.println(HSDES.genMAC(b)+"**"+new String(packet));


    }
}
